package com.nd.fastdp.org.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nd.fastdp.framework.exception.BusinessException;
import com.nd.fastdp.framework.pojo.constant.VerifyRespCodeEnum;
import com.nd.fastdp.framework.pojo.dto.DelParam;
import com.nd.fastdp.framework.pojo.dto.StateParam;
import com.nd.fastdp.org.convert.DeptConvert;
import com.nd.fastdp.org.convert.UserConvert;
import com.nd.fastdp.org.convert.UserRoleConvert;
import com.nd.fastdp.org.dao.UserMangAreaMapper;
import com.nd.fastdp.org.dao.UserMangDeptMapper;
import com.nd.fastdp.org.dao.UserMapper;
import com.nd.fastdp.org.dao.UserRoleMapper;
import com.nd.fastdp.org.model.bo.org.DeptBO;
import com.nd.fastdp.org.model.bo.position.PositionBO;
import com.nd.fastdp.org.model.bo.user.UserBO;
import com.nd.fastdp.org.model.bo.user.UserRoleBO;
import com.nd.fastdp.org.model.dto.user.*;
import com.nd.fastdp.org.model.entity.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PositionService positionService;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private UserMangAreaMapper userMangAreaMapper;

    @Autowired
    private UserMangDeptMapper userMangDeptMapper;

    @Override
    @Transactional
    public UserBO add(UserAddParam param) {

        User user = UserConvert.INSTANCE.from(param);

        if(userMapper.isExist(user.getCode())){
            throw new BusinessException(VerifyRespCodeEnum.CODE_EXIST);
        }

        userMapper.insert(user);

        return UserConvert.INSTANCE.to(user);
    }

    @Override
    public void del(DelParam param) {
        userMapper.del(param);
    }

    @Override
    public UserBO modify(UserModifyParam param) {

        User user = UserConvert.INSTANCE.from(param);

        if(userMapper.isExist(user.getId(), user.getCode())){
            throw new BusinessException(VerifyRespCodeEnum.CODE_EXIST);
        }

        userMapper.updateById(user);

        return get(user.getId());
    }

    @Override
    public void modifyState(StateParam param) {
        userMapper.updateState(param);
    }

    @Override
    public UserBO get(String id) {

        User dict = userMapper.selectById(id);

        return UserConvert.INSTANCE.to(dict);
    }

    @Override
    public UserBO getByCode(String code) {

        User dict = userMapper.getByCode(code);

        return UserConvert.INSTANCE.to(dict);
    }

    @Override
    public List<UserBO> listAllEnable() {

        List<User> users =  userMapper.listAllEnable();

        return UserConvert.INSTANCE.to(users);
    }

    @Override
    public List<UserBO> listAll() {

        List<User> users =  userMapper.listAll();

        return UserConvert.INSTANCE.to(users);
    }

    @Override
    public List<UserBO> findByRoleId(String roleId) {

        List<User> users =  userMapper.findByRoleId(roleId);

        return UserConvert.INSTANCE.to(users);
    }

    @Override
    public List<UserBO> list(UserListParam param) {

        List<User> users =  userMapper.list(param);

        return UserConvert.INSTANCE.to(users);
    }

    @Override
    public Page<UserBO> page(UserQueryParam param) {

        IPage<User> page =  userMapper.page(param.getPage(), param);

        return UserConvert.INSTANCE.to(page);
    }

    @Override
    @Transactional
    public void add(UserRoleAddParam param) {

        userRoleMapper.del(param.getUserId());

        UserRole userRole = null;
        for (String roleId : param.getRoleIds()){

            userRole = new UserRole();

            userRole.setUserId(param.getUserId());
            userRole.setRoleId(roleId);

            userRoleMapper.insert(userRole);
        }
    }

    @Override
    public void del(String userId, String roleId) {
        userRoleMapper.del(userId, roleId);
    }

    @Override
    @Transactional
    public void add(UserMangAreaAddParam param) {

        userMangAreaMapper.del(param.getUserId());

        UserMangArea userMangArea = null;
        for (String areaId : param.getAreaIds()){

            userMangArea = new UserMangArea();

            userMangArea.setUserId(param.getUserId());
            userMangArea.setAreaId(areaId);

            userMangAreaMapper.insert(userMangArea);
        }

    }



    @Override
    public List<UserBO> findUserByMangArea(String areaId) {

        List<UserMangArea> mangAreas = userMangAreaMapper.findByAreaId(areaId);

        List<User> users = new ArrayList<>();

        for (UserMangArea mangArea : mangAreas){
            users.add(userMapper.selectById(mangArea.getUserId()));
        }

        return UserConvert.INSTANCE.to(users);
    }

    @Override
    public List<UserBO> findManager(String areaId, String positionCode) {

        List<UserBO> result = new ArrayList<>();

        List<UserBO> users = findUserByMangArea(areaId);

        for (UserBO userBO : users){

            if(StringUtils.isNotEmpty(userBO.getEmployeePosition())){

                PositionBO positionBO = positionService.get(userBO.getEmployeePosition());

                if(positionBO.getCode().equals(positionCode)){
                    result.add(userBO);
                }
            }
        }

        return result;
    }

    @Override
    @Transactional
    public void add(UserMangDeptAddParam param) {

        userMangDeptMapper.del(param.getUserId());

        UserMangDept userMangDept = null;
        for (String deptId : param.getDeptIds()){

            userMangDept = new UserMangDept();

            userMangDept.setUserId(param.getUserId());
            userMangDept.setDeptId(deptId);

            userMangDeptMapper.insert(userMangDept);
        }
    }

    @Override
    public List<DeptBO> findMangDeptByUserId(String userId) {

        List<Dept> userMangDepts = userMangDeptMapper.findByUserId(userId);

        return DeptConvert.INSTANCE.to(userMangDepts);
    }

    @Override
    public List<UserRoleBO> findRoleByUserId(String userId) {

        List<UserRole> userRoles = userRoleMapper.findRoleByUserId(userId);

        return UserRoleConvert.INSTANCE.to(userRoles);
    }

    @Override
    public List<UserBO> listByRoleId(String roleId) {

        List<UserBO> result = new ArrayList<UserBO>();

        List<UserRole> userRoles = userRoleMapper.findUserByRoleId(roleId);
        for (UserRole userRole : userRoles){
            result.add(get(userRole.getUserId()));
        }

        return result;
    }
}
